package cn.ly.core.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorTest extends Thread{
	
	private int index;
	public ExecutorTest(int i){
		this.index = i;
	}
	
	public void run(){
		try{
			ThreadLocal tl = new ThreadLocal();
			tl.set(1);
			tl.set(2);
			System.out.println(tl.get());
			System.out.println("[" + index + "] start ...");
			Thread.sleep((int)(Math.random()*10000));
			System.out.println("[" + index + "] end" );
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static ExecutorService getPool(String pool,int n){
		if(pool.equals("newFixedThreadPool")){
			return Executors.newFixedThreadPool(n);            //ExecutorService代表了一个线程池，他的动态真正类型是ThreadPoolExecutor
		}else if(pool.equals("newCachedThreadPool")){
			return Executors.newCachedThreadPool();
		}
		return Executors.newSingleThreadExecutor(); 
	}
	
	public static void main(String[] args) {
		ExecutorService service = getPool("newFixedThreadPool",5);
		for(int i=0; i<10; i++){
			service.execute(new ExecutorTest(i));       //execute是一个异步方法，不等待返回结果，只是把runnable提交到线程池中
		}
		System.out.println("submit finish");
		service.shutdown();
	}
	
	/**
	 * Executors.newFixedThreadPool(int n)：返回一个ThreadPoolExecutor
	 * 1、创建一个可重用的、固定线程集合的线程池。
	 * 2、这个线程池中的线程以共享的方式访问一个没有大小限制的队列，这个队列就是LinkedBlockingQueue，任务从队尾进入，对头出去，先进先出原则。
	 * 3、当有Runnable任务提交到线程池中时，这个任务会被放到这个队列中。
	 * 4、BlockingQueue 实现是线程安全的。所以每个线程从队列中取到的任务是不可能重复的。
	 * 5、虽然任务在队列中是有序的，但是如果线程池中有多个线程，取到任务后，线程的启动顺序不定，所以执行顺序在比较小的时间范围内也是不定的。
	 *    但是在大的时间里，执行任务的先后顺序还是有序的
	 * 6、如果在关闭前的执行期间由于失败而导致任何线程终止，那么一个新线程将代替它执行后续的任务（如果需要）。
	 * 7、execute方法是异步的
	 */
	
	/**
	 * Executors.newCachedThreadPool()：返回一个ThreadPoolExecutor
	 * 1、创建一个可以根据需要、创建新线程的、线程池
	 * 2、以前的线程可以重用
	 * 3、对于执行很多短期异步任务的程序而言，这些线程池通常可提高程序性能。
	 * 4、调用 execute 将重用以前构造的线程（如果线程可用）。
	 * 5、如果现有线程没有可用的，则创建一个新线程并添加到池中。
	 * 6、终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
	 * 7、这个线程池中有一个SynchronousQueue。这是一个阻塞同步队列，但是当有任务到来时，线程池就会派出一个线程去处理任务，
	 *    如果线程池中没有线程了，就会创建一个新的线程去处理任务。
	 * 8、所以execute方法效果还是异步的，不会阻塞。
	 */
	
	/**
	 * Executors.newFixedThreadPool(int n)：返回一个ThreadPoolExecutor
	 * 1、创建一个只有一个线程的线程池。
	 * 2、这个线程池中的线程以共享的方式访问一个没有大小限制的队列，这个队列就是LinkedBlockingQueue，任务从队尾进入，对头出去，先进先出原则。
	 * 3、当有Runnable任务提交到线程池中时，这个任务会被放到这个队列中。
	 * 4、BlockingQueue 实现是线程安全的。所以每个线程从队列中取到的任务是不可能重复的。
	 * 5、虽然任务在队列中是有序的，但是如果线程池中有多个线程，取到任务后，线程的启动顺序不定，所以执行顺序在比较小的时间范围内也是不定的。
	 *    但是在大的时间里，执行任务的先后顺序还是有序的
	 * 6、如果在关闭前的执行期间由于失败而导致任何线程终止，那么一个新线程将代替它执行后续的任务（如果需要）。
	 * 7、execute方法是异步的
	 */

}
